Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge common code bases for TdsParserStateObject.cs (2) #1844

Closed
wants to merge 23 commits into from

Conversation

panoskj
Copy link
Contributor

@panoskj panoskj commented Nov 22, 2022

Second part of #1520. As I explained in this comment, #1843 does more or less the same, but I have already written the code for this PR. Perhaps you will find some use for it.

As for the code itself, you will notice I have left lots of #if directives, intentionally, to highlight the differences between the two versions, before deciding how to resolve them.

PS: either way, please try to merge one of these PRs as soon as possible. They will allow us to partially fix the async bug. A full fix would require SqlDataReader TdsParser too, if I remember correctly.

…ged behavior of CheckConnection for netfx, to make it same as netcore, affecting IsConnectionAlive).
internal partial class TdsParserStateObject
{
private static bool UseManagedSNI => false;

private SNIHandle _sessionHandle = null; // the SNI handle we're to work on
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should'nt this be removed to be replase by SessionHandle struct

Copy link
Contributor Author

@panoskj panoskj Nov 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean to replace SNIHandle with SessionHandle struct at line 32?

If yes, you can't do this because I have defined it as readonly ref. I needed to "add" the IsNull property to SNIHandle, so I encapsulated it in a struct. Then I added readonly ref so that this struct never allocates memory and is copied as if it was a plain reference. This is an optimization which is probably not needed, but I tried to make as little behavioral/performance changes as possible while refactoring.

Edit: to clarify, SessionHandle struct is only created and used in certain methods. There is a readonly ref SessionHandle in netcore version used in a similar way.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I see. I was asking myself about encapsulating like in netcore version that why I have read it too fast. Thanks for clarification

@codecov
Copy link

codecov bot commented Nov 22, 2022

Codecov Report

Patch coverage: 96.12% and project coverage change: +2.57 🎉

Comparison is base (a4f18ca) 70.82% compared to head (2e2dab5) 73.40%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1844      +/-   ##
==========================================
+ Coverage   70.82%   73.40%   +2.57%     
==========================================
  Files         292      224      -68     
  Lines       61777    36213   -25564     
==========================================
- Hits        43752    26581   -17171     
+ Misses      18025     9632    -8393     
Flag Coverage Δ
addons 92.88% <ø> (+0.49%) ⬆️
netcore 73.23% <96.12%> (-1.21%) ⬇️
netfx ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...c/Microsoft/Data/SqlClient/TdsParserSessionPool.cs 91.78% <ø> (+5.53%) ⬆️
...c/Microsoft/Data/SqlClient/TdsParserStateObject.cs 88.85% <95.55%> (+1.39%) ⬆️
...c/Microsoft/Data/SqlClient/TdsParserStateObject.cs 87.26% <96.66%> (+42.97%) ⬆️
...SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs 69.35% <100.00%> (+1.10%) ⬆️

... and 201 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@lcheunglci
Copy link
Contributor

Thanks @panoskj for making each method merge as a separate commit so it's easier to review especially when working with a fairly large file :)

@panoskj
Copy link
Contributor Author

panoskj commented Nov 23, 2022

@lcheunglci I'm glad you find smaller commits useful.

It should be mentioned that I wrote this code 7-8 months ago and now rebased it on the latest version. But meanwhile, I added some style changes in #1520. As a result, some of these style changes are missing in the merged file of this PR. It may look like a regression, but I intend to add another commit that brings them back again.

…Removed unnecessary casts. Removed unnecessary assignment. Added readonly specifier where possible.
Copy link

@bhugot bhugot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some quick change without changing behavior

private SessionHandle SessionHandle => new SessionHandle(_sessionHandle);

private bool TransparentNetworkIPResolution => _parser.Connection.ConnectionOptions.TransparentNetworkIPResolution;

internal bool _pendingData = false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make private this field and use HasPendingData property where it's not used

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These fields are used across many files, that's why I didn't touch them. But I now see they will help with merging TdsParser, so I will add them.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that was my point to change them and it's a quick harmless refactoring. Thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just added a commit implementing the requested change.

private SessionHandle SessionHandle => new SessionHandle(_sessionHandle);

private bool TransparentNetworkIPResolution => _parser.Connection.ConnectionOptions.TransparentNetworkIPResolution;

internal bool _pendingData = false;
internal bool _errorTokenReceived = false; // Keep track of whether an error was received for the result.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make private this field and add the same property with get/set on it as NetCore:

        internal bool HasReceivedError
        {
            get => _errorTokenReceived;
            set => _errorTokenReceived= value;
        }

@@ -35,12 +50,6 @@ internal partial class TdsParserStateObject
// Timeout variables
internal bool _attentionReceived = false; // NOTE: Received is not volatile as it is only ever accessed\modified by TryRun its callees (i.e. single threaded access)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make private this field and add the same property with get/set on it as NetCore:

        internal bool HasReceivedAttention
        {
            get => _attentionReceived;
            set => _attentionReceived= value;
        }

// the code but does not remember either. At some point, we need to research killing this
// logic.
private volatile int _allowObjectID;

internal bool _hasOpenResult = false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make private this field and use HasOpenResult property where it's not used

@@ -51,45 +60,6 @@ internal partial class TdsParserStateObject

internal bool _receivedColMetaData; // Used to keep track of when to fire StatementCompleted event.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make private this field and add the same property with get/set on it as NetCore:

        internal bool HasReceivedColumnMetadata
        {
            get => _receivedColMetaData;
            set => _receivedColMetaData= value;
        }

…expose the same interface as netcore version. This helps merging other files, such as TdsParser.
…ry assignments. Used discard to ignore out parameters, instead of an unused variable.
@panoskj
Copy link
Contributor Author

panoskj commented Nov 24, 2022

Please review this commit with special care. It may change the behavior of IsConnectionAlive method in some edge case for netfx (so that netfx behavior matches netcore). To me it looks like either the netcore version is correct, or both versions are correct (and their behavior is actually the same).

PS: we would have to look into the native driver's code to determine whether the behavior changed or not, that's why I am unsure. The method in question is SNINativeMethodWrapper.SNICheckConnection, specifically in the case it receives a null value.

@bhugot
Copy link

bhugot commented Jan 18, 2023

Any news on merging this @lcheunglci

@lcheunglci
Copy link
Contributor

Any news on merging this @lcheunglci

Yes, we'll get to reviewing it after the 5.1.0 release.

…rStateObject-2

# Conflicts:
#	src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs
@Wraith2
Copy link
Contributor

Wraith2 commented Jun 20, 2023

Can we get an update on this please? there's still a lot of work to be done with merges and this has been open a long time now.

@DavoudEshtehari DavoudEshtehari added this to the 5.2.0-preview3 milestone Jun 21, 2023
@DavoudEshtehari DavoudEshtehari added the ➕ Code Health Changes related to source code improvements label Jun 21, 2023
@DavoudEshtehari DavoudEshtehari requested review from Kaur-Parminder and removed request for lcheunglci June 21, 2023 16:11
@JRahnama
Copy link
Member

/azurepipelines run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@Wraith2
Copy link
Contributor

Wraith2 commented Jun 21, 2023

If this is too big or too old a changeset to be reviewed and merged it could be closed and individual pieces of the work re-done in smaller PR's.

@JRahnama
Copy link
Member

If this is too big or too old a changeset to be reviewed and merged it could be closed and individual pieces of the work re-done in smaller PR's.

I totally agree with you. Let's break this down in several PRs and merge them before the next preview release.

On some other notes, I was considering, just me this is not a team decision or official roadmap, converting the netfx to SDK style project and do some testing for code base merging. That would make our lives a lot easier I think. It would probably will give us a bit more complicated csproj, but one csproj which works for all of them.

@JRahnama
Copy link
Member

@panoskj will you be able to break this PR to couple of smaller changeset or you prefer someone else to do it?

@David-Engel
Copy link
Contributor

On the "breaking it up" suggestion. Troubleshooting the pipeline failures might be easier by breaking it up, too. I'd first try to make changes to the separate TdsParserStateObject.cs files to bring them closer to identical. Ideas for steps in individual PRs:

  1. Rename internal variables/properties to all match.
  2. Reorder methods/member variables to align the file layout as much as possible, keeping identical code together as much as possible. I might even add some regions and/or comments to help future diffs keep their alignment when common code is removed from each file. (No other changes so that reviewers don't have to scrutinize any differences between the large code blocks.)
  3. Move common code into a new common file. Avoid any changes within moved blocks of code.

@panoskj
Copy link
Contributor Author

panoskj commented Jul 8, 2023

@panoskj will you be able to break this PR to couple of smaller changeset or you prefer someone else to do it?

@JRahnama @Wraith2 I will be able to split the PR within the next 4 weeks - my free time is very limited right now. Luckily, most commits are independent, so it should be easy to split the PR.

The reason I made it so large, is because I thought it would take you even more time, in total, to review 10 PRs, judging from the time it took you to accept the previous, smaller PR. Also keep in mind this file has several more thousands of lines to be merged once this PR is accepted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
➕ Code Health Changes related to source code improvements
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants